User devices is a term that applies to computer systems such as desktop computers, smart televisions (TVs) and mobile computing devices such as laptop computers, mobile phones, tablets, “smart” watches, and glasses, to list a few examples.
Software that runs on the user devices can be generally classified as operating systems and software applications. The operating system manages the physical elements or hardware of the user devices such as its central processing unit (CPU) and peripherals. The operating system also presents well-defined Application Programming Interfaces (APIs) to the software applications. The software applications interact with the hardware of the user devices and can access its capabilities via the APIs of the operating system.
Software applications that interact with an operating system are also said to “run on top of” the operating system. Applications that run directly on top of an operating system are also known as native applications. One such software application is a virtual machine (VM).
VMs permit an isolated processing environment to exist on a user device. VMs present this isolated processing environment to other software applications that execute on top of the VMs. The VMs hide or abstract the details of the underlying hardware and/or operating system from the applications that run on top of the VMs. Applications that run on top of VMs of user devices are also known as user apps, or “apps.” Applications that run on top of VMs of host systems are also known as host applications.
Host systems are computer systems that developers use to develop the user apps and prepare the user apps for execution on the user devices. Developers use host applications and native applications on the host systems to develop and compile the source code of the user apps. The host systems, as their name implies, host the files that include the source code of the user apps and the compiled output. The compiled output is then installed on a user device and executed to run the user app on the user device. Often, the source code of the user apps is written using the Java programming language.
Java is a registered trademark of Oracle Corporation. Java source code is included within classes, and a Java compiler converts the source code for each Java class definition into its compiled output, also known as bytecode. Bytecode is typically a set of binary files that include platform-neutral instructions for implementing application behavior. Bytecode executes on VMs. The VMs interpret the bytecode, and execute corresponding native (e.g. machine-dependent) instructions on the target user device associated with the bytecode.
For example, a Java compiler accepts a source file named “MyClass.java” with source code that includes the class definition for named class “MyClass,” converts the source code to bytecode, and stores the bytecode in class file “MyClass.class.”
The term “platform” typically refers to an operating system of a user device or other computer system. One such platform is the Android platform. Android is a registered trademark of Google, Inc. Android is a mobile computing system operating system based on the Linux kernel. User devices that support the Android platform/OS are also known as Android user devices.
User apps that extend the functionality of Android devices are developed primarily in the Java programming language. Dalvik and ART are examples of Android-specific VMs upon which user apps execute.
The Dalvik VM cannot execute java bytecode directly. Dalvik requires that the java bytecode is first converted into a further form of Android-specific set of instructions known as Dalvik bytecode/Dalvik executable. Dalvik bytecode is stored in files having a “.dex” extension. A tool called “dx” is used to convert Java .class files into the .dex files. For this reason, Android user app developers often use terminology such as “Android user apps are compiled into dex files” as a shorthand for this process.
ART (Android Runtime) is a newer VM for Android that improves upon Dalvik. ART accepts dex files to maintain backwards compatibility to Dalvik. In addition, a new Android development tools suite called the Java Android Compiler Kit (Jack) can directly produce dex files from Java source code.
Resources are the non-source code additional files and static content used by a user app. Android resources include content such as layout definitions, user interface strings, plaintext and binary XML files, graphics files such as JPEG and bitmap images, and animation instructions, in examples. Resources are typically compiled into a binary format before they are packaged within the APK file. They can be accessed from code via unique resource ids for each of the resources.
Archives are files that include one or more computer files and optionally meta data of the computer files. The computer files can include text, or information in binary format, in examples. Archives are typically compressed to enable more efficient use of storage space of computer systems that store the archives. Archives also enable more efficient transfer of files when packaged within an archive, as compared to transfer of the individual files in uncompressed (i.e. “raw”) format. Examples of archives, and computer files included within the archives, include java class files included within a java archive, or JAR files, and dex files included within an Android application package (APK) archive.
Android application package (APK) is the package file format used to distribute and install application software and middleware onto Android user devices. It is an archive that is formatted in a fashion similar to ZIP and JAR archives. A typical APK includes an Android manifest file and sets of dex files and resources associated with the Android user app.
Deployment of a user app refers to the steps required to install and execute the user app on a user device. In the case of Android user apps, deployment is associated with sending an APK for the user app to the user device, unpacking the contents of the APK, and loading the classes and/or resources of the user app from the unpacked contents to execute/start the user app on the user device.
Class transformation is the process of modifying the bytecode of original classes and changed classes of an application such as a user app or host application. Class transformation techniques enable changes to the behavior of a user app without making changes to its original source code and/or resources. Class transformation is typically executed offline.
Android Instrumentation is a mechanism for hooking into the main lifecycle events of an Android user app. When a user app is running with instrumentation turned on, any Implementation classes of the user app will be instantiated before any other classes of the application code. This allows monitoring of all interactions that the Android platform has with the user app.
A class inheriting from an Android Activity class provides an atomic, focused event. Almost all Android activities enable interactions with the user. In one example, Activity classes can create a main graphical window within which a user interface (UI) can be placed, typically by means of Android resources.
Current methods of developing user apps for user devices have problems. One problem is the significant amount of time required to make changes to a user app and to then test the changes. This is known as the turnaround time.
Long turnaround time is a major issue for developing user apps on user devices such as Android user devices. Turnaround time includes the time associated with each change and retest of a user app, also known as a compile-uninstall-deploy-start cycle.
For each cycle, on a development system, developers first make changes to the source code and/resources of the user app and compile the changes. The changes to the classes and/or the resources are saved to a host file system of the developer system. A new archive is then created that includes the original classes and resources of the user app and the changes. Then, on the user device, the currently running instance of the user app is stopped, and its current archive/package file is uninstalled. The developer then deploys the new archive on the user device by unpacking its contents, and executing its unpacked contents to start the user app.
Typically, development of a user app requires applying hundreds or even thousands of these cycles in an iterative fashion. Turnaround time generally increases proportionally with the size of the user app being developed. While the turnaround time can be especially long when initially developing a user app, additions or bug fixes to an already released user app can also have significant turnaround times.
A few projects to date have been created in an attempt to address the problem of long turnaround time of user apps, but introduce more problems than they solve and therefore have little practical benefit. One project is Buck Exopackage by Facebook, and another is Mirror by Jimulabs.
Buck Exopackage provides the ability to load classes including application code of the user app at runtime, but has a number of problems. It has an intrusive setup that requires modification of the original production source code of the user app to leverage its features. This pollutes the production code of the user app. It also does not support changes to resources, and is limited to one software development build system for Android, the Buck build system. Finally, it requires extensive changes to build files.
Mirror provides the ability to prototype animation in UIs of Android user apps but has many limitations. While it can preview changes in resources of the user apps, it does not support changes to application code in classes and only supports previews of resource changes shown on the user device. This places the user app in a non-functional state.